// 数据上下文提供者
import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react';
import { Student, Teacher, Class, Grade, Attendance, AuditLog, Dormitory, dataUtils } from './models';
import { apiDataService } from './apiDataService';

// 定义上下文数据类型
interface DataContextType {
  // 实体数据
  students: Student[];
  teachers: Teacher[];
  classes: Class[];
  grades: Grade[];
  attendances: Attendance[];
  auditLogs: AuditLog[];
  dormitories: Dormitory[];
  
  // 关联数据
  classWithTeachers: Array<Class & { headTeacher?: Teacher }>;
  studentsWithClass: Array<Student & { classInfo?: Class }>;
  
  // 选项数据
  statusOptions: Array<{ value: string; label: string }>;
  stageOptions: Array<{ value: string; label: string }>;
  academyOptions: Array<{ value: string; label: string }>;
  
  // 状态
  loading: boolean;
  error: string | null;
  
  // 学生相关方法
  getStudentById: (id: string) => Student | undefined;
  createStudent: (student: Omit<Student, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
  updateStudent: (id: string, student: Partial<Student>) => Promise<void>;
  deleteStudent: (id: string) => Promise<void>;
  
  // 教师相关方法
  getTeacherById: (id: string) => Teacher | undefined;
  createTeacher: (teacher: Omit<Teacher, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
  updateTeacher: (id: string, teacher: Partial<Teacher>) => Promise<void>;
  deleteTeacher: (id: string) => Promise<void>;
  
  // 班级相关方法
  getClassById: (id: string) => Class | undefined;
  createClass: (cls: Omit<Class, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
  updateClass: (id: string, cls: Partial<Class>) => Promise<void>;
  deleteClass: (id: string) => Promise<void>;
  
  // 宿舍相关方法
  getDormitoryById: (id: string) => Dormitory | undefined;
  getDormitoryStudents: (dormitoryId: string) => Student[];
  getAvailableDormitories: () => Dormitory[];
  getDormitoriesByType: (type: string) => Dormitory[];
  
  // 成绩相关方法
  getGrades: () => Grade[];
  getGradesByStudentId: (studentId: string) => Grade[];
  createGrade: (grade: Omit<Grade, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
  
  // 考勤相关方法
  getAttendancesByStudentId: (studentId: string) => Attendance[];
  getAttendancesByClassId: (classId: string) => Attendance[];
  createAttendance: (attendance: Omit<Attendance, 'id' | 'createdAt' | 'updatedAt'>) => Promise<void>;
  
  // 刷新数据
  refreshData: () => Promise<void>;
  
  // 验证数据一致性
  validateData: () => Promise<{ isValid: boolean; errors: string[] }>;
  
  // 审计日志相关方法
  addAuditLog: (logData: Partial<AuditLog>) => Promise<void>;
}

// 创建上下文
const DataContext = createContext<DataContextType | undefined>(undefined);

// 导出DataContext供需要直接使用的组件使用
export { DataContext };

// 数据提供者组件接口
interface DataProviderProps {
  children: ReactNode;
}

// 数据提供者组件
export const DataProvider: React.FC<DataProviderProps> = ({ children }) => {
  const [students, setStudents] = useState<Student[]>([]);
  const [teachers, setTeachers] = useState<Teacher[]>([]);
  const [classes, setClasses] = useState<Class[]>([]);
  const [grades, setGrades] = useState<Grade[]>([]);
  const [attendances, setAttendances] = useState<Attendance[]>([]);
  const [auditLogs, setAuditLogs] = useState<AuditLog[]>([]);
  const [dormitories, setDormitories] = useState<Dormitory[]>([]);
  const [loading, setLoading] = useState<boolean>(true);
  const [error, setError] = useState<string | null>(null);
  
  // 定义学生状态选项
  const statusOptions = [
    { value: 'active', label: '在读' },
    { value: 'suspended', label: '休学' },
    { value: 'transferred', label: '转学' },
    { value: 'graduated', label: '毕业' }
  ];
  
  // 定义阶段选项
  const stageOptions = [
    { value: 'freshman', label: '专业阶段' },
    { value: 'sophomore', label: '专科阶段' },
    { value: 'junior', label: '实训阶段' },
    { value: 'zhuangao1', label: '专高阶段一' },
    { value: 'zhuangao2', label: '专高阶段二' },
    { value: 'zhuangao3', label: '专高阶段三' },
    { value: 'zhuangao4', label: '专高阶段四' },
    { value: 'zhuangao5', label: '专高阶段五' },
    { value: 'zhuangao6', label: '专高阶段六' },
    { value: 'shixun1', label: '实训阶段一' },
    { value: 'shixun2', label: '实训阶段二' },
    { value: 'shixun3', label: '实训阶段三' }
  ];
  
  // 定义学院选项 - 与models.ts保持一致
  const academyOptions = [
    { value: '人工智能', label: '人工智能' },
    { value: '数智传媒', label: '数智传媒' },
    { value: '鸿蒙生态开发', label: '鸿蒙生态开发' },
    { value: '云计算', label: '云计算' },
    { value: '元宇宙', label: '元宇宙' },
    { value: '市场部', label: '市场部' }
  ];

  // 加载所有数据 - 使用后端 API
  const loadAllData = async () => {
    setLoading(true);
    setError(null);
    
    try {
      // 从后端 API 加载数据
      const studentsData = await apiDataService.getStudents();
      
      // 特殊处理教师数据，确保即使失败也不会中断初始化
      let teachersData = [];
      try {
        teachersData = await apiDataService.getTeachers() || [];
      } catch (teacherError) {
        console.warn('获取教师数据失败，使用空数组:', teacherError);
        teachersData = [];
      }
      
      const classesData = await apiDataService.getClasses();
      const gradesData = await apiDataService.getGrades();
      const attendancesData = await apiDataService.getAttendances();
      const auditLogsData = await apiDataService.getAuditLogs();
      const dormitoriesData = await apiDataService.getDormitories();

      // 后端数据已经包含正确的统计信息，无需客户端计算
      setStudents(studentsData);
      setTeachers(teachersData);
      setClasses(classesData);
      setGrades(gradesData);
      setAttendances(attendancesData);
      setAuditLogs(auditLogsData);
      setDormitories(dormitoriesData);
    } catch (err) {
      console.error('Failed to load data:', err);
      setError('加载数据失败，请检查后端服务是否启动');
    } finally {
      setLoading(false);
    }
  };

  // 初始加载数据 - 直接从后端加载
  useEffect(() => {
    console.log('Starting data initialization - loading from backend API');
    
    const initializeData = async () => {
      console.log('Loading data from backend...');
      await loadAllData();
      
      // 记录加载的数据量
      console.log(`Data load complete from backend API`);
    };
    
    initializeData();

    // 订阅数据变更通知
    const unsubscribe = apiDataService.subscribeToChanges((entityType, changeType, entityId) => {
      console.log(`Data changed: ${entityType} ${changeType} ${entityId}`);
      // 数据发生变更时重新加载所有数据
      loadAllData();
    });

    return () => unsubscribe();
  }, []);

  // 关联数据计算
  const classWithTeachers = classes.map(cls => ({
    ...cls,
    advisor: teachers.find(t => t.id === cls.advisorId),
    lecturer: teachers.find(t => t.id === cls.lecturerId)
  }));

  const studentsWithClass = students.map(student => ({
    ...student,
    classInfo: classes.find(c => c.id === student.classId)
  }));

  // 学生相关方法
  const getStudentById = (id: string): Student | undefined => {
    return students.find(s => s.id === id);
  };

  const createStudent = async (student: Omit<Student, 'id' | 'createdAt' | 'updatedAt'>) => {
    try {
      await apiDataService.createStudent(student);
      // 数据服务会触发变更通知，从而重新加载数据
    } catch (err) {
      console.error('Failed to create student:', err);
      throw err;
    }
  };

  const updateStudent = async (id: string, student: Partial<Student>) => {
    try {
      await apiDataService.updateStudent(id, student);
      // 数据服务会触发变更通知，从而重新加载数据
    } catch (err) {
      console.error('Failed to update student:', err);
      throw err;
    }
  };

  const deleteStudent = async (id: string) => {
    try {
      await apiDataService.deleteStudent(id);
      // 数据服务会触发变更通知，从而重新加载数据
    } catch (err) {
      console.error('Failed to delete student:', err);
      throw err;
    }
  };

  // 宿舍相关方法
  const getDormitoryById = (id: string): Dormitory | undefined => {
    return dormitories.find(d => d.id === id || d._id === id);
  };
  
  const getDormitoryStudents = (dormitoryId: string): Student[] => {
    return students.filter(s => 
      (s.dormitoryId === dormitoryId || (s as any).dormitory === dormitoryId) && 
      s.status === 'active'
    );
  };
  
  const getAvailableDormitories = (): Dormitory[] => {
    return dormitories.filter(d => 
      d.status === 'active' && 
      (d.currentOccupancy || 0) < (d.capacity || 0)
    );
  };
  
  const getDormitoriesByType = (type: string): Dormitory[] => {
    if (type === 'all') return dormitories;
    return dormitories.filter(d => d.type === type);
  };

  // 教师相关方法
  const getTeacherById = (id: string): Teacher | undefined => {
    return teachers.find(t => t.id === id);
  };

  const createTeacher = async (teacher: Omit<Teacher, 'id' | 'createdAt' | 'updatedAt'>) => {
    try {
      await apiDataService.createTeacher(teacher);
    } catch (err) {
      console.error('Failed to create teacher:', err);
      throw err;
    }
  };

  const updateTeacher = async (id: string, teacher: Partial<Teacher>) => {
    try {
      await apiDataService.updateTeacher(id, teacher);
    } catch (err) {
      console.error('Failed to update teacher:', err);
      throw err;
    }
  };

  const deleteTeacher = async (id: string) => {
    try {
      await apiDataService.deleteTeacher(id);
    } catch (err) {
      console.error('Failed to delete teacher:', err);
      throw err;
    }
  };

  // 班级相关方法
  const getClassById = (id: string): Class | undefined => {
    return classes.find(c => c.id === id);
  };

  const createClass = async (cls: Omit<Class, 'id' | 'createdAt' | 'updatedAt'>) => {
    try {
      await apiDataService.createClass(cls);
    } catch (err) {
      console.error('Failed to create class:', err);
      throw err;
    }
  };

  const updateClass = async (id: string, cls: Partial<Class>) => {
    try {
      await apiDataService.updateClass(id, cls);
    } catch (err) {
      console.error('Failed to update class:', err);
      throw err;
    }
  };

  const deleteClass = async (id: string) => {
    try {
      await apiDataService.deleteClass(id);
    } catch (err) {
      console.error('Failed to delete class:', err);
      throw err;
    }
  };

  // 成绩相关方法
  const getGrades = (): Grade[] => {
    return grades;
  };
  
  const getGradesByStudentId = (studentId: string): Grade[] => {
    return grades.filter(grade => grade.studentId === studentId);
  };

  const createGrade = async (grade: Omit<Grade, 'id' | 'createdAt' | 'updatedAt'>) => {
    try {
      await apiDataService.createGrade(grade);
    } catch (err) {
      console.error('Failed to create grade:', err);
      throw err;
    }
  };

  // 考勤相关方法
  const getAttendancesByStudentId = (studentId: string): Attendance[] => {
    return attendances.filter(a => a.studentId === studentId);
  };

  const getAttendancesByClassId = (classId: string): Attendance[] => {
    return attendances.filter(a => a.classId === classId);
  };

  const createAttendance = async (attendance: Omit<Attendance, 'id' | 'createdAt' | 'updatedAt'>) => {
    try {
      await apiDataService.createAttendance(attendance);
    } catch (err) {
      console.error('Failed to create attendance:', err);
      throw err;
    }
  };

  // 刷新数据
  const refreshData = async () => {
    await loadAllData();
    
    // 刷新时也验证并修复数据一致性
    try {
      const validation = await dataService.validateAllData();
      if (!validation.isValid) {
        console.warn('数据一致性问题:', validation.errors);
        // 尝试修复数据一致性
        const classesWithUpdatedCount = dataUtils.updateClassStudentCount(classes, students);
        const dormitoriesWithUpdatedOccupancy = dataUtils.updateDormitoryOccupancy(dormitories, students);
        const dormitoriesWithUpdatedStudents = dataUtils.updateDormitoryStudents(dormitoriesWithUpdatedOccupancy, students);
        
        // 更新本地状态
        setClasses(classesWithUpdatedCount);
        setDormitories(dormitoriesWithUpdatedStudents);
        
        // 重新加载数据以确保与服务器同步
        await loadAllData();
      }
    } catch (err) {
      console.error('数据验证失败:', err);
    }
  };

  // 验证数据一致性
  const validateData = async () => {
    return apiDataService.validateAllData();
  };
  
  // 添加审计日志
  const addAuditLog = async (logData: Partial<AuditLog>) => {
    try {
      const currentUser = localStorage.getItem('currentUser') || 'system';
      const ipAddress = '127.0.0.1'; // 简化处理，实际项目中应获取真实IP
      
      const log: AuditLog = {
        id: `audit-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,
        timestamp: new Date().toISOString(),
        userId: currentUser,
        user: currentUser,
        action: logData.action || '',
        module: logData.entityType || 'unknown',
        moduleId: logData.entityId || '',
        details: logData.details || '',
        ipAddress,
        status: 'success'
      };
      
      // 创建或更新auditLogs数组
      setAuditLogs(prevLogs => [log, ...prevLogs]);
    } catch (error) {
      console.error('Failed to add audit log:', error);
    }
  };

  // 上下文值
  const contextValue: DataContextType = {
    students,
    teachers,
    classes,
    grades,
    attendances,
    auditLogs,
    dormitories,
    classWithTeachers,
    studentsWithClass,
    statusOptions,
    stageOptions,
    academyOptions,
    loading,
    error,
    getStudentById,
    createStudent,
    updateStudent,
    deleteStudent,
    getTeacherById,
    createTeacher,
    updateTeacher,
    deleteTeacher,
    getClassById,
    createClass,
    updateClass,
    deleteClass,
    getGrades,
    getGradesByStudentId,
    createGrade,
    getAttendancesByStudentId,
    getAttendancesByClassId,
    createAttendance,
    refreshData,
    validateData,
    addAuditLog
  };

  return (
    <DataContext.Provider value={contextValue}>
      {children}
    </DataContext.Provider>
  );
};

// 自定义Hook，方便组件使用数据上下文
export const useData = (): DataContextType => {
  const context = useContext(DataContext);
  if (context === undefined) {
    throw new Error('useData must be used within a DataProvider');
  }
  return context;
};

// 导出一个便捷的Hook，用于获取关联数据
export const useRelatedData = () => {
  const { classWithTeachers, studentsWithClass } = useData();
  return { classWithTeachers, studentsWithClass };
};

// 导出一个Hook，用于监听特定实体类型的数据变更
export const useEntityChanges = (entityType: string) => {
  const [changeCount, setChangeCount] = useState(0);
  const { refreshData } = useData();

  useEffect(() => {
    const unsubscribe = dataService.subscribeToChanges((type) => {
      if (type === entityType) {
        setChangeCount(prev => prev + 1);
        refreshData();
      }
    });

    return () => unsubscribe();
  }, [entityType, refreshData]);

  return changeCount;
};